<?php
/*
 * 微信
 * */
namespace app\common;


use think\facade\Db;
use think\Response;


class Wechat
{
    /**
     * 微信模板通知模板
     * @var     string
     * */
    public string $template;

    /**
     * 公众号消息加解密token
     * @var     string
     * */
    protected string $token = 'ktNzZjZC00ZDBlLThmMjAtMWQ0NjA3Nj';

    protected static array $result = [
        'code' => 0,
        'msg' => 'success',
        'data' => []
    ];

    //初始化返回值
    private static function init():void{
        self::$result = [
            'code' => 0,
            'msg' => 'success',
            'data' => []
        ];
    }

    public static function getConfig(int $id,$field=''){
        $wx = Db::name('wx_config')->cache(60)->find($id);
        if($field){
            return $wx ? ($wx[$field]??'') : '';
        }else{
            return $wx?:[];
        }
    }

    /**
     *
     * 接收公众号消息
     *
     * */
    public function mp():Response
    {
        $signature = input('signature/s','trim');
        $timestamp = input('timestamp/s','trim');
        $nonce = input('nonce/s','','trim');
        $echostr = input('echostr/s','','trim');
        $res = $echostr;
        try{
            if(!$signature || !$timestamp || !$nonce || !$echostr){
                throw new \Exception('data error');
            }

            $list = [$this->token,$nonce,$timestamp];
            sort($list);
            $hashcode = sha1(implode($list));

            if($hashcode !== $signature){
                throw new \Exception('verify error');
            }
        }catch (\Exception $e){
            //$echostr=$e->getMessage();
            //file_put_contents('1.txt',$echostr,FILE_APPEND);
            //接收消息
            $postObj = simplexml_load_string( file_get_contents("php://input") );
            if( strtolower( $postObj->MsgType) == 'event'){
                //如果是关注 subscribe 事件
                if( strtolower($postObj->Event == 'subscribe') ){
                    //回复用户消息(纯文本格式)
                    $toUser   = $postObj->FromUserName;
                    $fromUser = $postObj->ToUserName;
                    $nt     = time();
                    $msgType  =  'text';
                    $content  = '欢迎词';
                    $template = "<xml>
                                <ToUserName><![CDATA[%s]]></ToUserName>
                                <FromUserName><![CDATA[%s]]></FromUserName>
                                <CreateTime>%s</CreateTime>
                                <MsgType><![CDATA[%s]]></MsgType>
                                <Content><![CDATA[%s]]></Content>
                                </xml>";
                    $res = sprintf($template, $toUser, $fromUser, $nt, $msgType, $content);
                }
            }
        }
        return $res;
    }

    /**
     * 自定义菜单
     * @param array $data
     * @return array
     * */
    public static function menu(array $data,$wid=1):array
    {
        self::init();
        $access_token = self::getAccessToken($wid);

        $api_url='https://api.weixin.qq.com/cgi-bin/menu/create?access_token='.$access_token;
        $result = httpCurl($api_url, json_encode($data,JSON_UNESCAPED_UNICODE));
        $result = json_decode($result,true);
        if(!isset($result['menuid'])){
            self::$result['code'] = $result['errcode'] ?? 211;
            self::$result['msg'] = $result['errmsg'] ?? '';
        }
        return $result;
    }

    /**
     * 获取公众号带参二维码
     * @param   int $id
     * @param   array $param
     * @throws
     * @return array
     * */
    public static function mpQr(int $id,array $param):array
    {
        $result = [
            'code' => 0,
            'msg' => 'success',
            'data' => []
        ];
        try{
            $access_token = self::getAccessToken($id);
            $url = 'https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token='.$access_token;
            $param = json_encode($param);
            $res = httpCurl($url,$param);
            $res = json_decode($res,true);
            if(!$res){
                throw new \Exception('网络错误',201);
            }
            $result['data'] = $res;
        }catch (\Exception $e){
            $result['code'] = $e->getCode();
            $result['msg'] = $e->getMessage();
        }
        return $result;
    }


    /**
     * 获取接口统一调用凭据access_token
     *
     *
     * @param   int $id
     * @throws
     * @return string
     */
    public static function getAccessToken(int $id = 1):string
    {

        $wx = self::getConfig($id);
        $nt = intval(getDateTime('U'));
        if(!$wx['access_token'] || $wx['refresh_time'] < $nt){

            //获取access_token
            //https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
            $url='https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$wx['app_id'].'&secret='.$wx['app_secret'];
            $result = httpCurl($url);

            $redata = json_decode($result,true);
            if(isset($redata['access_token'])){
                $wx = [
                    'id' => $wx['id'],
                    'access_token' => $redata['access_token'] ?? '',
                    'expires_in' => $redata['expires_in'] ?? 0,
                    'get_time' => $nt,
                    'refresh_time' => $nt + $redata['expires_in'] ?? 0
                ];
                Db::name('wx_config')->update($wx);
            }else{
                file_put_contents('./get_access_token.txt',$result.PHP_EOL,8);
                return false;
            }
        }

        return $wx['access_token'];
    }

    /**
     * 获取微信公众号授权code
     * @param  string  $app_id        回调跳转地址
     * @param  string  $uri        回调跳转地址
     * @param  int     $scope      授权域：snsapi_userinfo 公众号授权，snsapi_base 公众号静默授权，snsapi_login 扫码登录
     * @param  bool     $type       0公众号授权，1二维码登录
     * @param  string  $state      自定义参数
     * @return string
     * */
    public static function mpCodeUrl(string $app_id,string $uri,int $scope = 0,bool $type = false,string $state=''):string
    {
        $scope_arr = ['snsapi_userinfo','snsapi_base','snsapi_login'];
        $states = $state?'&state='.$state:'';
        $api = $type ? 'https://open.weixin.qq.com/connect/qrconnect' : 'https://open.weixin.qq.com/connect/oauth2/authorize';
        return $api.'?appid='.$app_id.'&redirect_uri='.$uri.'&response_type=code&scope='.$scope_arr[$scope].$states.'#wechat_redirect';
    }

    /**
     * 获取公众号授权access_token
     *
     * @param  array   $config   微信配置数组
     * @param  string  $code     授权code
     * @return array
     * 正确返回json
     * {
     *   "access_token":"ACCESS_TOKEN",
     *   "expires_in":7200,
     *   "refresh_token":"REFRESH_TOKEN",
     *   "openid":"OPENID",
     *   "scope":"SCOPE"
     * }
     *
     * 错误返回json
     * {"errcode":40029,"errmsg":"invalid code"}
     *
     * */
    public static function getLoginAccessToken(string $code, int $id=1):array
    {
        self::init();
        $config = self::getConfig($id);
        $url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid=' . $config['app_id'] . '&secret=' . $config['app_secret'] . '&code=' . $code . '&grant_type=authorization_code';
        $redata = json_decode(httpCurl($url), true);
        if (isset($redata['access_token'])) {
            self::$result['data'] = $redata;
        } else {
            file_put_contents('./log/wx/get_login_access_token.txt',json_encode($redata).PHP_EOL,8);
            self::$result['code'] = $redata['errcode'] ?? 211;
            self::$result['msg'] = $redata['errmsg'] ?? '';
        }
        return self::$result;
    }

    /**
     * 刷新登录授权AccessToken
     *
     * @param   int  $id
     * @param   string  $refresh_token
     * @return  array
     * @throws
     */
    public static function refreshAccessToken(int $id,string $refresh_token):array
    {
        self::init();
        $config = self::getConfig($id);
        $url = 'https://api.weixin.qq.com/sns/oauth2/refresh_token?appid='.$config['app_id'].'&grant_type=refresh_token&refresh_token='.$refresh_token;
        $redata = json_decode(httpCurl($url),true);
        if (isset($redata['access_token'])) {
            $nt = time();
            $wx = [
                'id'=>$id,
                'access_token' => $redata['access_token'] ?? '',
                'expires_in' => $redata['expires_in'] ?? 0,
                'get_time' => $nt,
                'refresh_time'=>$nt + $redata['expires_in'] ?? 0
            ];
            Db::name('wx_config')->update($wx);
            self::$result['data'] = $wx;
        } else {
            file_put_contents('./refresh_access_token.txt',json_encode($redata).PHP_EOL,8);
            self::$result['code'] = $redata['errcode'] ?? 211;
            self::$result['msg'] = $redata['errmsg'] ?? '';
        }
        return self::$result;
    }


    /**
     * 检验登录授权凭证（access_token）是否有效
     *
     * @param   string $access_token
     * @param   string $open_id
     * @return  bool
     * 正确json
     * {"errcode":0,"errmsg":"ok"}
     * 错误json
     * {"errcode":40003,"errmsg":"invalid openid"}
     * */
    public static function checkAccessToken(string $access_token,string $open_id):bool
    {
        $url = "https://api.weixin.qq.com/sns/auth?access_token=$access_token&openid=$open_id";
        $res = json_decode(httpCurl($url),true);
        if($res['errcode'] === 0){
            return true;
        }else{
            return false;
        }
    }

    /**
     * 获取用户资料
     *
     * @param   string $access_token
     * @param   string $openid
     * @return  array
     * 正确返回json
     * {
     *   "openid":" OPENID",
     *   "nickname": NICKNAME,
     *   "sex":"1",
     *   "province":"PROVINCE"
     *   "city":"CITY",
     *   "country":"COUNTRY",
     *   "headimgurl":"http://thirdwx.qlogo.cn/mmopen/g3Mon",
     *   "privilege":[ "PRIVILEGE1" "PRIVILEGE2"     ],
     *   "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
     * }
     *
     * 错误返回json
     *
     * {"errcode":40003,"errmsg":" invalid openid "}
     *
     */
    public static function getUserInfo(string $access_token,string $openid):array
    {
        self::init();
        $url = 'https://api.weixin.qq.com/sns/userinfo?access_token='.$access_token.'&openid='.$openid.'&lang=zh_CN';
        $res = json_decode(httpCurl($url),true);
        if(!isset($res['errcode'])){
            self::$result['data'] = $res;
        }else{
            self::$result['code'] = $res['errcode'] ?? 211;
            self::$result['msg']= $res['errmsg'] ?? '';
        }
        return self::$result;
    }


    /**
     * 获取jsapi_ticket
     * @param int $id
     * @throws
     * @return string
     * */
    public static function getJsApiTicket(int $id = 1):string
    {
        $wx = self::getConfig($id);
        $nt = getDateTime('U');
        if(!$wx['jsapi_ticket'] || $wx['jsapi_expires_time'] < $nt){
            $access_token = self::getAccessToken($id);
            $url='https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token='.$access_token.'&type=jsapi';
            $res = httpCurl($url);
            $result = json_decode($res,true);
            if(isset($result['ticket'])){
                $wx=[
                    'id'=>$wx['id'],
                    'jsapi_ticket'=>$result['ticket'] ?? '',
                    'jsapi_expires_time'=>$nt+7200
                ];
                Db::name('wx_config')->update($wx);
            }else{
                //file_put_contents('4.txt',json_encode($result).PHP_EOL,8);
                return false;
            }
        }
        return $wx['jsapi_ticket'];
    }

    /**
     * 获取JSSDK签名
     * @param int $wid
     * @param string $url
     * @return array
     * */
    public static function jsSdkData(int $wid,string $url):array
    {
        $appId = self::getConfig($wid,'app_id');
        $timestamp = getDateTime('U'); // 必填，生成签名的时间戳
        $nonceStr =  substr(md5($timestamp),0,16); // 必填，生成签名的随机串
        $jsapi_ticket = self::getJsApiTicket($wid);
        $data = [
            'url'=>$url,
            'jsapi_ticket'=>$jsapi_ticket,
            'timestamp'=>$timestamp,
            'noncestr'=>$nonceStr,
        ];
        ksort($data);
        $str = self::ToUrlParams($data);
        $data['signature'] = sha1($str);
        //$data['str'] = $str;
        $data['app_id'] = $appId;
        unset($data['jsapi_ticket'],$data['url']);
        return $data;
    }


    /**
     * 扫服务号二维码打开小程序-增加或修改二维码规则
     * @param string $appid 要跳转的小程序appid
     * @param string $path 要跳转小程序页面路径
     * @param string $prefix url
     * @param int $wid 公众号id
     * @param int $isEdit 编辑标志位，0 表示新增二维码规则，1 表示修改已有二维码规则（注意，已经发布的规则，不支持修改）
     *
     * @return bool
     *
     * */
    public static function qrJump(string $appid,string $path,string $prefix,int $wid=1,int $isEdit=0):bool
    {
        $accessToken = self::getAccessToken($wid);
        $url = 'https://api.weixin.qq.com/cgi-bin/wxopen/qrcodejumpadd?access_token='.$accessToken;
        $param = [
            'prefix' => $prefix,
            'appid' => $appid,
            'path' => $path,
            'is_edit' => $isEdit
        ];
        $re = httpCurl($url,json_encode($param));
        $res = json_decode($re,true);
        if(!$res['errcode']){
            $publishUrl = 'https://api.weixin.qq.com/cgi-bin/wxopen/qrcodejumppublish?access_token='.$accessToken;
            $param = [
                'prefix' => $prefix,
            ];
            httpCurl($publishUrl,json_encode($param));
        }else{
            file_put_contents('qr_jump.txt',$re.PHP_EOL,8);
        }
        return !$res['errcode'];
    }

    /**
     * 获取小程序码
     * @param   string $access_token    接口调用凭据
     * @param   string $scene           自定义参数,最大32个可见字符，只支持数字，大小写英文以及部分特殊字符：!#$&'()*+,/:;=?@-._~，其它字符请自行编码为合法字符
     * @param   string $page            小程序页面地址,必须是已经发布的小程序存在的页面（否则报错），例如 pages/index/index, 根路径前不要填加 /,不能携带参数（参数请放在scene字段里），如果不填写这个字段，默认跳主页面
     * @param   array $data            [
     * 'width'=>'二维码的宽度，单位 px，最小 280px，最大 1280px',
     * 'auto_color'=>'自动配置线条颜色，如果颜色依然是黑色，则说明不建议配置主色调，默认 false',
     * 'line_color'=>'auto_color 为 false 时生效，使用 rgb 设置颜色 例如 {"r":"xxx","g":"xxx","b":"xxx"} 十进制表示',
     * 'is_hyaline'=>'是否需要透明底色，为 true 时，生成透明底色的小程序码'
     * ]
     * @return mixed|string
     * 如果调用成功，会直接返回图片二进制内容，如果请求失败，会返回 JSON 格式的数据。
     * */
    public static function getUnlimited(string $access_token,string $scene,string $page='',array $data=[]):array
    {
        self::init();
        $url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=$access_token";
        if($page){
            $data['page'] = trim($page,'/');
        }
        $data['scene'] = $scene;
        $per = json_encode($data);
        $result = httpCurl($url,$per);
        $res = json_decode($result,true);
        if(isset($res['errcode'])){
            self::$result['code'] = $res['errcode'] ?? 211;
            self::$result['msg'] = $res['errmsg'] ?? '';
        }else{
            self::$result['data'] = $result;
        }
        return self::$result;
    }

    /**
     * 公众号模板消息推送
     *  'touser' => 'openid',
     *  'appid'=>'wxc576fcf4f34b172e',
    'template_id' => 'L9Mj-ibuMFZWB4WY3YBuJXq266a5_-smcFbYX0vSQcc',
    'url'=>'', //选填
    'mini_program' => [//选填
    'appid'=>'wxc522ab8ba2f344b0',
    'pagepath' => 'pages/index/index',
    ],
    'data' => [
    'first'=>[
    'value'=>'您有一张优惠券即将到期！',
    'color'=>''   //选填
    ],
    'name'=>['value'=>'新人优惠券','color'=>''],
    'expDate'=>['value'=>'2020-12-16','color'=>''],
    'remark'=>['value'=>'查看详情','color'=>''],
    ]
     * @param array $template
     * @param int $id   微信配置id
     * @return array
     */
    public static function sendTemplate(array $template,int $id = 1):array
    {
        self::init();
        $template = json_encode($template);

        $access_token = self::getAccessToken($id);
        //发送模板数据接口
        $url = 'https://api.weixin.qq.com/cgi-bin/message/template/send?access_token='.$access_token;

        $res = httpCurl($url,$template);
        $result = json_decode($res,true);
        if($result['errcode'] != 0){
            self::$result['code'] = $result['errcode'] ?? 211;
            self::$result['msg'] = $result['errmsg'] ?? '';
        }
        return self::$result;
    }

    /**
     * 统一服务消息发送
     *
     * $data = [
    'touser' => $openid,
    'mp_template_msg'=>[
    'appid'=>'wxc576fcf4f34b172e',
    'template_id' => 'L9Mj-ibuMFZWB4WY3YBuJXq266a5_-smcFbYX0vSQcc',
    'url'=>'',
    'mini_program' => [
    'appid'=>'wxc522ab8ba2f344b0',
    'pagepath' => 'pages/index/index',
    ],
    'data' => [
    'first'=>['value'=>'您有一张优惠券即将到期！','color'=>''],
    'name'=>['value'=>'新人优惠券','color'=>''],
    'expDate'=>['value'=>'2020-12-16','color'=>''],
    'remark'=>['value'=>'查看详情','color'=>''],
    ]
    ],
    'weapp_template_msg' => [
    'template_id'=>'',//小程序模板ID
    'page' =>'',	//小程序页面路径
    'form_id' =>'',	//小程序模板消息formid
    'data' => [],	//小程序模板数据
    'emphasis_keyword' => ''//小程序模板放大关键词
    ]
    ];
     * @param array $template
     * @param int $id   微信配置id
     * @return array
     * @throws
     * */
    public static function sendUniform(array $template,int $id = 1):array
    {
        self::init();
        $template = json_encode($template);

        //echo $template;
        $access_token = self::getAccessToken($id);
        //dump($access_token);
        //发送模板数据接口
        $url = 'https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send?access_token='.$access_token;

        $res1 = httpCurl($url,$template);
        $result = json_decode($res1,true);
        if($result['errcode'] != 0){
            self::$result['code'] = $result['errcode'] ?? 211;
            self::$result['msg'] = $result['errmsg'] ?? '';
        }
        return self::$result;
    }

    /**
     * 小程序订阅消息发送
     *
     * $template = [
    'touser' => $openid,
    'miniprogram_state' => '',//
    'template_id'=>'',//小程序模板ID
    'page' =>'',	//小程序页面路径
    'data' => [],	//小程序模板数据
    'emphasis_keyword' => ''//小程序模板放大关键词
    ];
     * @param array $template
     * @param int $id   微信配置id
     * @return array
     * @throws
     * */
    public static function sendSubscribe(array $template,int $id = 1):array
    {
        self::init();
        $template = json_encode($template);

        //echo $template;
        $access_token = self::getAccessToken($id);
        //dump($access_token);
        //发送模板数据接口
        $url = 'https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token='.$access_token;

        $res2 = httpCurl($url,$template);
        $result = json_decode($res2,true);
        if($result['errcode'] != 0){
            self::$result['code'] = $result['errcode'] ?? 211;
            self::$result['msg'] = $result['errmsg'] ?? '';
        }
        return self::$result;
    }


    /**
     * 检查一段文本是否含有违法违规内容v1/v2
     * @param string $content  要检测的文本内容，长度不超过 500KB
     * @param string $openId    用户的openid（用户需在近两小时访问过小程序）
     * @param int $scene        场景枚举值（1 资料；2 评论；3 论坛；4 社交日志）
     * @param int $id       微信配置id
     * @return bool
     * 频率限制：单个 appId 调用上限为 4000 次/分钟，2,000,000 次/天
     * result->label：100 正常；10001 广告；20001 时政；20002 色情；20003 辱骂；20006 违法犯罪；20008 欺诈；20012 低俗；20013 版权；21000 其他
     * */
    public static function msgSecCheck(string $content,string $openId = '',int $scene = 1,int $id = 1):bool
    {
        self::init();
        $access_token = self::getAccessToken($id);

        $url = 'https://api.weixin.qq.com/wxa/msg_sec_check?access_token='.$access_token;
        if($openId){
            //v2版
            $data = [
                'openid' => $openId,
                'scene' => $scene,
                'version' => 2,
                'content' => $content
            ];
            $res3 = httpCurl($url,json_encode($data,JSON_UNESCAPED_UNICODE));
            $result = json_decode($res3,true);
            return $result['result']['label']??100;

        }else{
            //v1版
            $result = httpCurl($url,json_encode(['content'=>$content],JSON_UNESCAPED_UNICODE));
            $result = json_decode($result,true);
            return $result['errcode'] == "87014"?false:true;
        }

    }

    /**
     * 校验一张图片是否含有违法违规内容。
     * @param string $media    要检测的图片文件，格式支持PNG、JPEG、JPG、GIF，图片尺寸不超过 750px x 1334px
     * @param int $id       微信配置id
     * @return bool
     * 频率限制：单个 appId 调用上限为 2000 次/分钟，200,000 次/天 （ 图片大小限制：1M ）
     * */
    public static function imgSecCheck(string $media,int $id = 1):bool
    {
        $access_token = self::getAccessToken($id);
        $url = 'https://api.weixin.qq.com/wxa/img_sec_check?access_token='.$access_token;
        $media = new \CURLFile($media);
        $result = httpCurl($url,['media'=>$media]);
        //file_put_contents('./img_request.txt',$result.PHP_EOL,8);
        $result = json_decode($result,true);
        return $result['errcode'] == "87014"?false:true;
    }

    /**
     * 异步校验图片/音频是否含有违法违规内容。
     * @param string $media_url    要检测的多媒体url
     * @param string $openid    用户的openid（用户需在近两小时访问过小程序）
     * @param int $media_type   1:音频;2:图片
     * @param int $scene   场景枚举值（1 资料；2 评论；3 论坛；4 社交日志）
     * @param int $id       微信配置id
     * @return array
     * 频率限制：单个 appId 调用上限为 2000 次/分钟，200,000 次/天；文件大小限制：单个文件大小不超过10M
     * */
    public static function mediaCheckAsync(string $media_url, string $openid,int $media_type = 2,int $scene=1,int $id = 1):array
    {
        self::init();
        $access_token = self::getAccessToken($id);
        $url = 'https://api.weixin.qq.com/wxa/media_check_async?access_token='.$access_token;
        $result = json_decode(httpCurl($url,['media_url'=>$media_url,'media_type'=>$media_type,'version'=>2,'scene'=>$scene,'openid'=>$openid]),true);
        if($result['errcode'] != 0){
            self::$result['code'] = $result['errcode'] ?? 211;
            self::$result['msg'] = $result['errmsg'] ?? '';
        }
        return self::$result;
    }


    /**
     * 获取小程序session key
     *
     * @param   string $code        授权code
     * @param   int $id       微信配置id
     * @return  array
     * */
    public static function getSessionKey(string $code,int $id=1):array
    {
        self::init();
        $config = self::getConfig($id);
        if(!$code) return ['code'=>-2,'msg'=>'无效访问'];
        $url = "https://api.weixin.qq.com/sns/jscode2session?appid={$config['app_id']}&secret={$config['app_secret']}&js_code={$code}&grant_type=authorization_code";
        $ret = httpCurl($url);
        $res = json_decode($ret,true);
        //return dump($arr);
        if(isset($res['openid']) && isset($res['session_key'])){
            self::$result['data'] = [
                'openid'=>$res['openid'],
                'session_key'=>$res['session_key'],
                'unionid'=>$res['unionid'] ?? "",
            ];
        }else{
            self::$result['code'] = $res['errcode'] ?? 211;
            self::$result['msg'] = $res['errmsg'] ?? '';
        }
        return self::$result;
    }
    /**
     * 敏感信息解密
     *
     * @param   string $encryptedData   加密敏感信息
     * @param   string $iv              解密key
     * @param   string $appId           应用ID
     * @param   string $session_key     登录session key
     * @return  array
     * */
    public static function deCode(string $encryptedData,string $iv,string $session_key,int $id=1):array
    {
        $IllegalAesKey = -41001;
        $IllegalIv = -41002;
        $IllegalBuffer = -41003;
        $DecodeBase64Error = -41004;
        $result = [
            'code' => 0,
            'msg' => 'success',
            'data' => []
        ];
        $wx = self::getConfig($id);
        try{
            if (strlen($session_key) != 24) {

                throw new \Exception('无效的key', $IllegalAesKey);
            }
            $aesKey = base64_decode($session_key);


            if (strlen($iv) != 24) {
                throw new \Exception('无效的秘钥',$IllegalIv);
            }
            $aesIV = base64_decode($iv);

            $aesCipher = base64_decode($encryptedData);

            $rest = openssl_decrypt( $aesCipher, "AES-128-CBC", $aesKey, 1, $aesIV);

            $dataObj = json_decode( $rest );
            if( $dataObj  == NULL )
            {
                throw new \Exception('解密失败',$DecodeBase64Error);
            }
            if( $dataObj->watermark->appid != $wx['app_id'] )
            {
                throw new \Exception('非法密文',$IllegalBuffer);
            }
            $result['data'] =  json_decode($rest,true);

        }catch (\Exception $e){
            $result['code'] = $e->getCode();
            $result['msg'] = $e->getMessage();
        }

        return $result;
    }

    /**
     * 格式化参数格式化成url参数
     * @param   array $values
     * @return  string
     */
    public static function ToUrlParams(array $values):string
    {
        $buff = "";
        foreach ($values as $k => $v)
        {
            if($k != "sign" && $v != "" && !is_array($v)){
                $buff .= $k . "=" . $v . "&";
            }
        }
        return trim($buff, "&");
    }

}

